#include "gamedialog.h"
#include "gamedialogitem.h"
#include "gamedialogmanager.h"
#include "gamewindow.h"
#include "gameanimation.h"
#include "gametable.h"
#include "player.h"
#include <QPainter>
#include "ghostboarditems.h"

GameDialogBg::GameDialogBg(GameDialogManager *m)
    :QGraphicsObject(m)
{
    setOpacity(0.5);
}

QRectF GameDialogBg::boundingRect() const{
    int width = GameWindow::SCENE_WIDTH;
    int height = GameWindow::SCENE_HEIGHT;
    return QRectF(-width/2, -height/2, width, height);
}

void GameDialogBg::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){
    painter->fillRect(boundingRect(), Qt::black);
}


//Game dialog skeleton
GameDialog::GameDialog(GameDialogManager* parent, GameDialogBg* f)
    :QGraphicsObject(parent), _manager(parent), _fore(f)
{
    setVisible(false);
    _fore->setVisible(false);
    showAnim = new GameParAnimation(this);
    hideAnim = new GameParAnimation(this);
    connect(hideAnim, SIGNAL(finished()), this, SLOT(hideFinished()));
}

GameTable* GameDialog::getGameTable(){
    return getDialogManager()->getGameWindow()->getTable();
}

void GameDialog::moveToBackEnd(){
    setVisible(false);
    _fore->setVisible(false);
    releaseTableBlock();
}

void GameDialog::moveToFrontEnd(){
    setVisible(true);
    _fore->setVisible(true);
    gainTableBlock();
}

void GameDialog::gainTableBlock(){
    getDialogManager()->getGameWindow()->getTable()->setEnabled(false);
}

void GameDialog::releaseTableBlock(){
    getDialogManager()->getGameWindow()->getTable()->setEnabled(true);
}

void GameDialog::startDialog(){
    gainTableBlock();
    _fore->setVisible(true);
    showAnim->start();
    setVisible(true);
}

void GameDialog::startDialogNoLock(){
    showAnim->start();
    setVisible(true);
}

void GameDialog::hideStarted(){
    hideAnim->start();
    _fore->setVisible(false);
}

void GameDialog::hideFinished(){
    e.exit(1);
    setVisible(false);
    releaseTableBlock();
}

// Message Box
GameMessageBox::GameMessageBox(GameDialogManager *m, GameDialogBg* f)
    :GameDialog(m, f), _msg("")
{
    _bg = QPixmap(":/dialog/images/msgbox_bg.png");
    showAnim->addFade(this, 0, 1, 300);
    hideAnim->addFade(this, 1, 0, 300);
    _msg_anim = new QPropertyAnimation( this, "message_index", this );
    connect( showAnim, SIGNAL(finished()), _msg_anim, SLOT(start()) );
    connect( _msg_anim, SIGNAL(valueChanged(QVariant)), this, SLOT(updateMessage()) );
    _msg_index = 0;
}

int GameMessageBox::execDialog(){
    startDialog();
    int r = e.exec();
    //enter local event loop to wait for user input
    return r;
}

void GameMessageBox::setText(QString s){
    _msg = s;
    _msg_anim->setDuration( MSG_INTERVAL * s.length() * 200 );
    _msg_anim->setStartValue( 0 );
    _msg_anim->setEndValue( MSG_INTERVAL * s.length() );
}

QRectF GameMessageBox::boundingRect() const{
    return QRectF(-_bg.width()/2,-_bg.height()/2, _bg.width(), _bg.height());
}

void GameMessageBox::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){
    painter->drawPixmap(-_bg.width()/2,-_bg.height()/2,_bg);
    QString msg( _msg );
    msg.chop( MSG_INTERVAL * ( msg.length() - _msg_index ) );
    //qDebug() << MSG_INTERVAL * ( msg.length() - _msg_index ) << msg;
    painter->drawText(boundingRect(), Qt::AlignCenter, msg );
}

//Message info box
GameInfoMessageBox::GameInfoMessageBox(GameDialogManager *m, GameDialogBg *f)
    :GameMessageBox(m, f)
{
    okButton = new GameDialogButton(this);
    connect(okButton, SIGNAL(pressed()), this, SLOT(hideStarted()));
}

//tao request
GameTaoRequestDialog::GameTaoRequestDialog(GameDialogManager *m, GameDialogBg *f)
    :GameMessageBox(m, f)
{

    GameDialogButton* red = new GameDialogTaoButton(this, RED);
    GameDialogButton* yel = new GameDialogTaoButton(this, YELLOW);
    GameDialogButton* bla = new GameDialogTaoButton(this, BLACK);
    GameDialogButton* blu = new GameDialogTaoButton(this, BLUE);
    GameDialogButton* gre = new GameDialogTaoButton(this, GREEN);


    _taoButtons << red << yel << bla << blu << gre;
    int width = _taoButtons[0]->boundingRect().width();
    int total = width*5;
    for(int i = 0; i<_taoButtons.length(); i++){
        _taoButtons[i]->moveBy(-total/2+width/2+i*width, 0);
        connect(_taoButtons[i], SIGNAL(pressed()), this, SLOT(hideStarted()));
    }
}

void GameTaoRequestDialog::chooseColor(GSColor c){
    color = c;
}

GSColor GameTaoRequestDialog::execDialog(){
    startDialog();
    int r = e.exec();
    if(r == 1)
        return color;
    else
        return WHITE;
        //white indicates null result
}



//slot request
GameSlotRequestDialog::GameSlotRequestDialog(GameDialogManager *m, GameDialogBg *f)
    :GameDialog(m, f)
{
    tips = new DialogTips(this, "Choose a slot");
    tips->moveBy(0, GameWindow::SCENE_HEIGHT/2-DialogTips::HEIGHT/2);
    QPointF e = pos();
    QPointF s = e;
    s.setY(pos().y()+DialogTips::HEIGHT);
    showAnim->addMove(this, s, e, 300);
    hideAnim->addMove(this, e, s, 300);
}

GhostSlot* GameSlotRequestDialog::execDialog(){
    startDialogNoLock();
    int c = e.exec();
    //enter local event loop to wait for user input
    if(c == 1)
        return receivedSlot;
    else
        return 0;
}

QRectF GameSlotRequestDialog::boundingRect() const{
    return QRectF();
}

void GameSlotRequestDialog::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){

}


void GameSlotRequestDialog::receiveClickOnSlot(GhostSlot *g){
    receivedSlot = g;
    hideAnim->start();
}

//tile request
GameTileRequestDialog::GameTileRequestDialog(GameDialogManager *m, GameDialogBg *f)
    :GameDialog(m, f)
{
    tips = new DialogTips(this, "Choose a tile");
    tips->moveBy(0, GameWindow::SCENE_HEIGHT/2-DialogTips::HEIGHT/2);
    QPointF e = pos();
    QPointF s = e;
    s.setY(pos().y()+DialogTips::HEIGHT);
    showAnim->addMove(this, s, e, 300);
    hideAnim->addMove(this, e, s, 300);
}

VillageTile* GameTileRequestDialog::execDialog(){
    startDialogNoLock();
    int c = e.exec();
    //enter local event loop to wait for user input
    if(c == 1)
        return receivedTile;
    else
        return 0;
}

QRectF GameTileRequestDialog::boundingRect() const{
    return QRectF();
}

void GameTileRequestDialog::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){

}


void GameTileRequestDialog::receiveClickOnTile(VillageTile *t){
    receivedTile = t;
    hideAnim->start();
}


//dice
GameDiceRequestDialog::GameDiceRequestDialog(GameDialogManager *m, GameDialogBg *f)
    :GameDialog(m, f)
{
    showAnim->addFade(this, 0, 1, 300);
    hideAnim->addFade(this, 1, 0, 300);
}


void GameDiceRequestDialog::execDialog(int num){
    for(int i = 0; i<num; i++){
        GameDialogDice* dice = new GameDialogDice(this);
        int width = dice->boundingRect().width();
        _dices << dice;
        dice->moveBy(-width*(num-1)/2+i*width, 0);
    }
    startDialog();
    grabMouse();
    e.exec();
}

void GameDiceRequestDialog::mousePressEvent(QGraphicsSceneMouseEvent *event){
    if(_dices.length()!=0){
        for(int i = 0; i<_dices.length(); i++){
            if(_dices[i]->isActive()){
                _dices[i]->stop();
                if(i==_dices.length()-1){
                    ungrabMouse();
                    this->hideStarted();
                    e.exit();
                }
                break;
            }
        }
    }
}

QRectF GameDiceRequestDialog::boundingRect() const{
    return QRectF();
}

void GameDiceRequestDialog::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){

}


void GameDiceRequestDialog::hideStarted(){
    hideAnim->start();
}

void GameDiceRequestDialog::clear(){
    for(int i=0; i<_dices.length(); i++){
        delete _dices[i];
    }
    _dices.clear();
}

//player
GamePlayerRequestDialog :: GamePlayerRequestDialog(GameDialogManager *m, GameDialogBg *bg)
    :GameDialog(m,bg)
{
    _bg = QPixmap(":/common/images/head_bg.png");
    tips = new DialogTips(this, "Choose a player");
    tips->moveBy(0, GameWindow::SCENE_HEIGHT/2-DialogTips::HEIGHT/2);
    setPlayerHeads();
    showAnim->addFade(this, 0, 1, 300);
    hideAnim->addFade(this, 1, 0, 300);
}

Player* GamePlayerRequestDialog::execDialog(bool alive)
{
    showLive = alive;
    startDialog();
    int r = e.exec();
    //enter local event loop to wait for user input
    if(r==1)
        return _selectedPlayer;
    else
        return 0;
}

void GamePlayerRequestDialog::setPlayerHeads()
{
    QList<Player*> playerList = this->getGameTable()->getPlayerList();
    QList<GSColor> PlayerColors;
    for(int i=0;i<playerList.size();i++){
        Player* currentPlayer = playerList.at(i);
        if(showLive){
            if(!currentPlayer->isDead())
                PlayerColors.append(currentPlayer->getGhostBoard()->getGSColor());
        }
        else{
            if(currentPlayer->isDead())
                PlayerColors.append(currentPlayer->getGhostBoard()->getGSColor());
        }
    }
    GSColor currentColor = this->getGameTable()->getCurrentPlayer()->getGhostBoard()->getGSColor();



    //int removeIndex = PlayerColors.indexOf(currentColor);
    PlayerColors.removeOne(currentColor);

    int moveDis = GameDialogHeadButton::headWidth;
    for(int i=0;i<PlayerColors.size();i++){
        GameDialogHeadButton* playerHead = new GameDialogHeadButton(this,PlayerColors.at(i));
        qDebug() << "color: " << PlayerColors.at(i);
        connect(playerHead,SIGNAL(click(GameDialogHeadButton*)),SLOT(receivedPlayerHead(GameDialogHeadButton*)));
        playerHead->moveBy((moveDis+GAP)*(i-1),0);
    }

}

void GamePlayerRequestDialog::receivedPlayerHead(GameDialogHeadButton * hd)
{
    _selectedPlayer = hd->getSelectedPlayer();
    this->hideStarted();
}

QRectF GamePlayerRequestDialog::boundingRect() const{
    return QRectF(-_bg.width()/2,-_bg.height()/2, _bg.width(), _bg.height());
}

void GamePlayerRequestDialog::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){
    painter->drawPixmap(-_bg.width()/2,-_bg.height()/2,_bg);
}
